package com.cooksys.film_rental.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.cooksys.film_rental.dao.RentalDao;
import com.cooksys.film_rental.model.City;
import com.cooksys.film_rental.model.Customer;
import com.cooksys.film_rental.model.Inventory;
import com.cooksys.film_rental.model.Payment;
import com.cooksys.film_rental.model.Rental;
import com.cooksys.film_rental.model.Staff;

@Repository("RentalDao")
@Transactional
public class RentalDaoImpl implements RentalDao {

	@Autowired(required = true)
	private SessionFactory sessionFactory;

	/**
	 * 
	 * @return the current session from the internal {@link SessionFactory}
	 */
	public Session currentSession() {
		return sessionFactory.getCurrentSession();
	}

	@Override
	public Rental getRentalByRentalId(Integer rentalId) {
		Session session = currentSession();

		// returns a record from the RENTAL table as an Rental object
		// based on the given rentalId, the table's primary key
		String hql = "from Rental r where r.rentalId = :rentalId";

		Query query = session.createQuery(hql);
		query.setInteger("rentalId", rentalId);

		return (Rental) query.list().get(0);

	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Rental> searchRentalsByStaff(Staff staff) {
		Session session = currentSession();

		String hql = "from Rental r where r.staff = :staff";
		Query query = session.createQuery(hql);
		query.setEntity("staff", staff);

		return query.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Rental> searchRentalsByCustomer(Customer customer) {
		Session session = currentSession();

		String hql = "from Rental r where r.customer = :customer";
		Query query = session.createQuery(hql);
		query.setEntity("customer", customer);

		return query.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Rental> searchRentalsByInventory(Inventory inventory) {
		Session session = currentSession();

		String hql = "from Rental r where r.inventory = :inventory";
		Query query = session.createQuery(hql);
		query.setEntity("inventory", inventory);

		return query.list();
	}

	@Override
	public Rental getRentalByPayment(Payment payment) {
		Session session = currentSession();

		String hql = "select p.rental from Payment p where p = :payment";
		Query query = session.createQuery(hql);
		query.setEntity("payment", payment);

		return (Rental) query.list().get(0);
	}

	@Override
	public Rental save(Rental rental) {
		Session session = currentSession();
		Serializable id = session.save(rental);
		return (Rental) session.get(Rental.class, id);
	}

	@Override
	public void delete(Rental rental) {
		Session session = currentSession();
		session.delete(rental);

	}

	@Override
	public void update(Rental rental) {
		Session session = currentSession();
		session.update(rental);

	}

}
